"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 人为因素
Case Name   : gs_dump导出过程中，对数据对象进行增删改查操作
Create At   : 2020-10-22
Owner       : n@ningyali
Description :
    1、建表进行插入及增删改查操作
    2、gs_dump此表
    3、gs_dump过程中对表进行增删改查操作
    4、gs_dump结束，查询表
    5、删除表，进行恢复操作
Expect      :
    1、成功
    2、gs_dump成功
    3、不影响数据库操作
    4、恢复成功，数据与dump时数据一致
    5、成功
History     :
    Modified by @wan005 2021/10/19:修改断言信息，dump过程中修改表内容会导致dump数据不确定
"""
import unittest
from yat.test import Node
from yat.test import macro

from testcase.utils.CommonSH import *
from testcase.utils.Common import *
from testcase.utils.Constant import *
from testcase.utils.ComThread import *


class GsDumpAndDml(unittest.TestCase):
    primary_sh = CommonSH('PrimaryDbUser')
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        self.log.info('------------Opengauss_Reliability_Human_Case018:开始执行------------')
        self.primary_root_node = Node(node='PrimaryRoot')
        self.primary_user_node = Node(node='PrimaryDbUser')
        self.com = Common()
        self.Constant = Constant()
        self.t_name = 'test_humanfactor018'
        self.dump_file_name = 'test_humanfactor018.sql'

    def test_main(self):
        self.log.info("------------建表进行插入及增删改查操作------------")
        create_table_cmd = f'''drop table if exists {self.t_name}; 
                            create table {self.t_name}(id int,name varchar(50),name1 varchar(50),name2 varchar(50));
                            '''
        insert_cmd = f"insert into {self.t_name} values (generate_series(1,1000000), '测试reliability_humanfactor018', " \
            f"'insert', '写入数据');"
        update_cmd = f"update {self.t_name} set name = name||'new';"
        delete_cmd = f"delete from {self.t_name} where id <= 10;"
        select_cmd = f"select count(*) from {self.t_name}"
        sql_cmd = create_table_cmd + insert_cmd + update_cmd + delete_cmd + select_cmd
        self.log.info(sql_cmd)
        msg = self.primary_sh.executDbSql(sql_cmd)
        self.log.info(msg)
        for err_msg in self.Constant.SQL_WRONG_MSG:
            self.assertNotIn(err_msg, msg)

        self.log.info("-------------gs_dump此表---------------")
        dump_thread = ComThread(self.primary_sh.dumpFile, args=(self.dump_file_name, f'-t {self.t_name}', None, False))
        dump_thread.setDaemon(True)
        dump_thread.start()

        time.sleep(0.1)

        self.log.info("------------gs_dump过程中对表进行增删改查操作------------")
        insert_cmd = f"insert into {self.t_name} values (generate_series(1,100), '测试reliability_humanfactor018', " \
            f"'insert', '写入数据');"
        sql_cmd = insert_cmd + update_cmd + delete_cmd + select_cmd
        self.log.info(sql_cmd)
        msg = self.primary_sh.executDbSql(sql_cmd)
        self.log.info(msg)
        for err_msg in self.Constant.SQL_WRONG_MSG:
            self.assertNotIn(err_msg, msg)

        self.log.info("---------------校验gs_dump结果----------------")
        dump_thread.join(60 * 5)
        dump_result = dump_thread.get_result()
        self.log.info(dump_result)
        self.assertTrue(dump_result)

        self.log.info("---------------gs_dump结束，查询表----------------")
        self.log.info(select_cmd)
        msg = self.primary_sh.executDbSql(select_cmd)
        self.log.info(msg)
        self.assertIn('1000080', msg)

        self.log.info("---------------删除表----------------")
        drop_cmd = f'''drop table {self.t_name}'''
        self.log.info(drop_cmd)
        msg = self.primary_sh.executDbSql(drop_cmd)
        self.log.info(msg)
        self.assertIn(self.Constant.TABLE_DROP_SUCCESS, msg)

        self.log.info("-------------进行恢复操作---------------")
        self.com.file_sql_execute(self.primary_user_node, self.dump_file_name, 1)

        self.log.info("---------------恢复后查询表----------------")
        self.log.info(select_cmd)
        msg = self.primary_sh.executDbSql(select_cmd)
        self.log.info(msg)
        self.assertIn('1 row', msg)

    def tearDown(self):
        drop_cmd = f'''drop table {self.t_name}'''
        self.log.info(drop_cmd)
        msg = self.primary_sh.executDbSql(drop_cmd)
        self.log.info(msg)

        shell_cmd = f"rm -rf {self.dump_file_name}; ls {self.dump_file_name}"
        self.log.info(shell_cmd)
        msg = self.primary_user_node.sh(shell_cmd).result()
        self.log.info(msg)
        self.log.info('------------Opengauss_Reliability_Human_Case018:执行完成------------')
